package com.ww.springboot.boot.algorithm.stack;

import lombok.SneakyThrows;

import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

/**
 * 描述：画出迷宫 默认是正方形的迷宫 优化代码
 *
 * @author wanwei
 * @since 2021-06-26 14:42
 */
public class MIGongPaintingDemo2 extends JFrame {

    public MIGongPaintingDemo2() {
        add(new MIGongPaintingDemo2.Composition());

        new Thread(() -> method()).start();
    }

    //坐标
    public static int x = 0;
    public static int y = 0;

    public static String info = "";

    //路径
    public static final StackSelf<Integer> stack = new StackSelf<>();
    //坐标
    public static final StackSelf<String> stacks = new StackSelf<>();

    private static final int[][] arrays = {
            {1, 1, 0, 0, 0, 0, 0, 0, 0, 0},
            {0, 1, 0, 0, 1, 0, 0, 0, 0, 0},
            {0, 1, 1, 1, 1, 1, 0, 1, 1, 0},
            {0, 0, 0, 1, 1, 1, 0, 0, 1, 0},
            {0, 0, 0, 1, 1, 1, 0, 0, 1, 0},
            {0, 0, 0, 0, 1, 1, 1, 0, 1, 0},
            {0, 0, 0, 0, 1, 0, 1, 1, 1, 1},
            {1, 1, 1, 1, 1, 0, 0, 1, 1, 0},
            {1, 0, 0, 0, 0, 0, 0, 0, 0, 0},
            {1, 1, 1, 1, 1, 1, 1, 1, 1, 1}};

    public static void main(String[] args) {
        JFrame frame = new MIGongPaintingDemo2();
        frame.setTitle("迷宫");
        frame.setSize(830, 600);
        frame.setLocationRelativeTo(null);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setVisible(true);
    }

    public static void method() {
        // 上 右 下 右
        int type = 0;
        stacks.push(x + "," + y);
        while (x != arrays.length - 1 || y != arrays.length - 1) {
            //上下左右都不能走则回退 如果无路可退则-》无路可走
            if (type > 3) {
                if (stack.empty()) {
                    info = "无路可走!";
                    return;
                }
                //反向退回
                type = stack.pop();
                stacks.pop();
                //还原坐标
                returnIndex(type);
                //修改上一路径
                type++;
                continue;
            }
            //不往回走
            if (!stack.isEmpty() && Math.abs(stack.peek() - type) == 2) {
                type++;
                continue;
            }
            int oldX = x;
            int oldY = y;
            //修改坐标
            changeIndex(type);
            //判断是否可达
            if (x >= 0 && y >= 0 && x < 10 && y < 10 && arrays[y][x] == 1 && !stacks.contains(x + "," + y)) {
                stack.push(type);
                stacks.push(x + "," + y);
                type = 0;
            }else{
                //不可达则还原坐标
                y = oldY;
                x = oldX;
                type++;
            }
        }
        info = "恭喜你,逃出迷宫";
    }

    private static void returnIndex(int type) {
        switch (type) {
            case 0: y++;
                break;
            case 1: x--;
                break;
            case 2: y--;
                break;
            case 3: x++;
                break;
        }
    }

    private static void changeIndex(int type) {
        switch (type) {
            case 0: y--;
                break;
            case 1: x++;
                break;
            case 2: y++;
                break;
            case 3: x--;
                break;
        }
    }


    static class Composition extends JPanel {

        public Composition() {
            Timer timer = new Timer(100, new MIGongPaintingDemo2.Composition.Refresh());
            timer.start();
        }


        @Override
        protected void paintComponent(Graphics g) {
            super.paintComponent(g);

            stack.paint(g);
            stacks.paint(g, -200);

            for (int i = 0; i < arrays.length; i++) {
                for (int j = 0; j < arrays[i].length; j++) {
                    if (arrays[j][i] == 0) {
                        g.setColor(Color.gray);
                    } else {
                        g.setColor(Color.white);
                    }
                    g.fillRect(100 + i * 20, 100 + j * 20, 20, 20);
                    g.setColor(Color.black);
                    g.drawRect(100 + i * 20, 100 + j * 20, 20, 20);
                }
            }

            g.setColor(Color.red);

            g.setFont(new Font("宋体", Font.PLAIN, 30));
            g.drawString(info, 300, 50);

            for (String s : stacks.getCollection()) {
                String[] array = s.split(",");
                g.setColor(Color.red);
                g.fillRect(100 + Integer.valueOf(array[0]) * 20, 100 + Integer.valueOf(array[1]) * 20, 20, 20);
                g.setColor(Color.black);
                g.drawRect(100 + Integer.valueOf(array[0]) * 20, 100 + Integer.valueOf(array[1]) * 20, 20, 20);
            }
        }


        class Refresh implements ActionListener {
            @Override
            public void actionPerformed(ActionEvent e) {
                //重画
                repaint();
            }
        }

    }

}
